﻿using IRepositoryBll;
using IRepositoryDal;
using RepositoryEntity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RepositoryBll
{
  public   class WorkFlow_InstanceBll : BaseDeleteBll<WorkFlow_Instance>, IWorkFlow_InstanceBll
    {
        /// <summary>
        /// 工作流实例
        /// </summary>
        private IWorkFlow_InstanceDal _workFlow_InstanceDal;
        private IUserInfoDal _userInfoDal;
        private IConsumableInfoDal _consumableInfoDal;
        private IWorkFlow_ModelDal _workFlow_ModelDal;
        private IWorkFlow_InstanceStepDal _workFlow_InstanceStepDal;
        private IDepartmentInfoDal _departmentInfoDal;
        private RepositoryDbContext _dbContext;
        public WorkFlow_InstanceBll(IWorkFlow_InstanceDal workFlow_InstanceDal , IUserInfoDal userInfoDal ,
            IConsumableInfoDal consumableInfoDal , IWorkFlow_ModelDal workFlow_ModelDal , IDepartmentInfoDal departmentInfoDal , 
            RepositoryDbContext dbContext , IWorkFlow_InstanceStepDal workFlow_InstanceStepDal) : base(workFlow_InstanceDal)
        {
            _workFlow_InstanceDal = workFlow_InstanceDal;
            _userInfoDal = userInfoDal;
            _consumableInfoDal = consumableInfoDal;
            _workFlow_ModelDal = workFlow_ModelDal;
            _departmentInfoDal = departmentInfoDal;
            _dbContext = dbContext;
            _workFlow_InstanceStepDal = workFlow_InstanceStepDal;
        }

        /// <summary>
        /// 添加流程实例
        /// </summary>
        /// <param name="workFlow_Instance"></param>
        /// <param name="departmentID"></param>
        /// <returns></returns>
        public bool AddWorkFlow_Instance(WorkFlow_Instance workFlow_Instance, string departmentId ,out string msg)
        {
            //查询部门领导
            var departmentInfo = _departmentInfoDal.GetEntitiesDb().Where(d => !d.IsDelete).FirstOrDefault(d => d.ID == departmentId);
            if (string.IsNullOrEmpty(departmentInfo.LeaderID))
            {
                msg = "请选择有领导的部门";
                return false;
            }

            //创建流程步骤
            WorkFlow_InstanceStep workFlow_InstanceStep = new WorkFlow_InstanceStep()
            {
                ID = Guid.NewGuid().ToString(),
                CreateTime = DateTime.Now,
                InstanceId = workFlow_Instance.ID,
                ReviewerId = departmentInfo.LeaderID,
                ReviewerStatus = WorkFlow_InstanceStep.InstanceStepStatus.审核中
            };

            //打开事务
            using (var transaction = _dbContext.Database.BeginTransaction())
            {
                bool isSuccess1 = _workFlow_InstanceDal.Add(workFlow_Instance);
                bool isSuccess2 = _workFlow_InstanceStepDal.Add(workFlow_InstanceStep);
                if (isSuccess1 && isSuccess2)
                {
                    msg = "请求成功";
                    transaction.Commit();
                    return true;
                }
                else
                {
                    msg = "请求失败";
                    transaction.Rollback();
                    return false;
                }
            }
        }

        /// <summary>
        /// 作废操作
        /// </summary>
        /// <param name="workFlow_instanceId"></param>
        /// <param name="userInfo"></param>
        /// <returns></returns>
        public bool CancelWorkFlow_Instance(string workFlow_instanceId, UserInfo userInfo)
        {

            WorkFlow_Instance entity = null;
            //是超级管理员的时候，可以帮别人作废流程
            if (userInfo.IsAdmin)
            {
                //查询要修改的流程实例
                entity = _workFlow_InstanceDal.GetEntitiesDb().FirstOrDefault(w => w.ID == workFlow_instanceId);
            }
            else //不是超级管理员只能作废自己申请的流程
            {
                //查询要修改的流程实例
                entity = _workFlow_InstanceDal.GetEntitiesDb().FirstOrDefault(w => w.ID == workFlow_instanceId && w.Creator == userInfo.ID);
            }

            if (entity == null)
            {
                return false;
            }

            //打开事务
            using (var transaction = _dbContext.Database.BeginTransaction())
            {
                entity.Status = WorkFlow_Instance.InstanceStepStatus.作废;
                //作废流程实例
                bool isSuccess1 = _workFlow_InstanceDal.Update(entity);

                //查询流程实例下的所有流程步骤
                var workFlow_InstanceSteps = _workFlow_InstanceStepDal.GetEntitiesDb().Where(wi => wi.InstanceId == workFlow_instanceId).ToList();
                foreach (var item in workFlow_InstanceSteps)
                {
                    //只有还在审核的流程步骤，才可以修改为作废。
                    if (item.ReviewerStatus == WorkFlow_InstanceStep.InstanceStepStatus.审核中)
                    {
                        item.ReviewerStatus = WorkFlow_InstanceStep.InstanceStepStatus.作废;
                    }
                }

                //更新流程步骤状态，改为作废
                bool isSuccess2 = _workFlow_InstanceStepDal.Updates(workFlow_InstanceSteps) > 0;
                if (isSuccess1 && isSuccess2)
                {
                    transaction.Commit();
                    return true;
                }
                else
                {
                    transaction.Rollback();
                    return false;
                }
            }
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="page"></param>
        /// <param name="limit"></param>
        /// <param name="count"></param>
        /// <param name="description"></param>
        /// <returns></returns>
        public object GetWorkFlow_InstancelListByPage(int page, int limit, out int count, string description)
        {
            //获取工作流实例表信息集合
            var workFlow_Instancel = _workFlow_InstanceDal.GetEntitiesDb().Where((u => u.IsDelete == false));

            if (!string.IsNullOrEmpty(description))
            {
                workFlow_Instancel = workFlow_Instancel.Where(u => u.Description.Contains(description));

            }

            //连表查询
            var tempList = (from wi in workFlow_Instancel
                            join cr in _consumableInfoDal.GetEntitiesDb().Where(c => !c.IsDelete)
                            on wi.OutGoodsId equals cr.ID into tempCwC
                            from cw in tempCwC.DefaultIfEmpty()

                            join m in _workFlow_ModelDal.GetEntitiesDb().Where(c => !c.IsDelete)
                            on wi.ModelId equals m.ID into tempCmC
                            from cm in tempCmC.DefaultIfEmpty()

                            join u in _userInfoDal.GetEntitiesDb().Where(u => !u.IsDelete)
                            on wi.Creator equals u.ID into tempUwC
                            from uu in tempUwC.DefaultIfEmpty()
                            select new
                            {
                                wi.ID,
                                wi.CreateTime,
                                wi.Reason,
                                wi.Status,
                                wi.OutNum,
                                
                                wi.Description,
                                ModelId = cm.Title,
                                OutGoodsId = cw.Name,
                                cw.Name,
                                uu.UserName
                            });

            //统计数据数量
            count = workFlow_Instancel.Count();
            tempList = tempList.Skip((page - 1) * limit).Take(limit);
            var list = tempList.ToList().Select(u =>
            {
                string statusStr = u.Status.ToString();
                return new
                {
                    u.ID,
                    u.UserName,
                   
                    Status = statusStr,
                    u.Reason ,
                    u.ModelId,
                    u.OutNum  ,
                   u.OutGoodsId,
                   u.Description,
                   u.Name,
                    CreateTime = u.CreateTime.ToString("yyyy-MM-dd HH:mm:ss")
                };
            });

            return list;
        }
    }
}
